﻿from dataclasses import dataclass, field

# 寄存器标号的枚举
Code = 0
Status = 1
IDTR = 2
RvBA = 3
PTR0 = 4
PTR1 = 5
PTR2 = 6
PTR3 = 7
RetAddr = 11
Stack = 14

# 标签的枚举
IntEN = 1
Error = 1 << 1
Trapped = 1 << 2
Masked = 1 << 3
Privilege = 1 << 8
CacheEnable = 1 << 10
TLBEnable = 1 << 11
PageEnable = 1 << 12
Block = 1 << 13
Master = 1 << 14
Slave = 1 << 15

# 访问权限的枚举
Read = 1
Write = 2
Execute = 4
Priv = 8


@dataclass
class IO:
    address: int
    size: int
    data: int
    status: bool


class Trap(Exception):
    def __init__(self, code: int):
        self.code: int = code

    def what(self):
        return self.code


class VMException(Exception):
    def __init__(self, code: int, addr: int, message: str):
        self.code: int = code
        self.where: int = addr
        self.what: str = message

    def __str__(self):
        return f"Violation {self.code} at {self.where}: {self.what}"


class IllegalInstruction(VMException):
    def __init__(self, addr: int):
        super().__init__(0x1c0, addr, "Undefined instruction")

    def __str__(self):
        return super().__str__()


class AccessViolate(VMException):
    def __init__(self, addr: int):
        super().__init__(0x1d0, addr, "Access violation")

    def __str__(self):
        return super().__str__()


class AddrMisalign(VMException):
    def __init__(self, addr: int):
        super().__init__(0x1d1, addr, "Address misalign")

    def __str__(self):
        return super().__str__()


class PageFault(VMException):
    def __init__(self, addr: int):
        super().__init__(0x1d2, addr, "Page fault")

    def __str__(self):
        return super().__str__()


class IllegalPage(VMException):
    def __init__(self, addr: int):
        super().__init__(0x1d3, addr, "Illegal page")

    def __str__(self):
        return super().__str__()


class MathError(VMException):
    def __init__(self, addr: int):
        super().__init__(0x1e0, addr, "Math error")

    def __str__(self):
        return super().__str__()


class DefaultFault(VMException):
    def __init__(self, addr: int, message: str):
        super().__init__(0x1ff, addr, message)

    def __str__(self):
        return super().__str__()
